/************************************************************************
Copyright 2003, 2004, 2005, 2006, 2007, 2008 Grid Technology Research Center,
National Institute of Advanced Industrial Science and Technology.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************/

package jp.aist.gtrc.plus.reserve;

import java.util.Calendar;

import jp.aist.gtrc.plus.scheduler.SchedulerOptions;


import org.apache.log4j.Logger;

public class ReserveOperationManager implements ReserveServer {

	private final ReserveManager rsvMgr;
	private final ReserveOperator reserver;
	private final CancelOperator canceler;
	private final ModifyOperator modifier;
	private final DestroyOperator destroier;
	private final CommitOperator commiter;
	private final AbortOperator aborter;
	private final GetStatusOperator watcher;

	private final ReserveLogger rsvLogger;

	protected static final  Logger logger = Logger.getLogger(ReserveOperationManager.class);

	public ReserveOperationManager(ReserveManager rsvMgr,
			ReserveNodeNormalizer normalizer, SchedulerOptions options) throws ReserveException {

		this.rsvMgr = rsvMgr;
		commiter = new CommitOperator(rsvMgr);
		aborter = new AbortOperator(rsvMgr);

		reserver = new ReserveOperator(rsvMgr, normalizer, aborter);
		modifier = new ModifyOperator(rsvMgr, normalizer, aborter);

		// commiter will be used for cancelOfOwner/destroyOfOwner
		canceler = new CancelOperator(rsvMgr, normalizer, commiter, aborter);
		destroier = new DestroyOperator(rsvMgr, normalizer, commiter, aborter);

		watcher = new GetStatusOperator(rsvMgr);

		rsvLogger = new ReserveLogger(options.getReserveFilePath());

	}

	protected void recoverFromRecorder() throws ReserveException {

		ReserveOperation lastOpe = rsvMgr.getReserveRecorder().loadOperation();
		if (lastOpe != null) {
			rsvMgr.startCurrentOperation(lastOpe);
		}

	}

	public ReserveId reserve(ReserveRequest req) throws ReserveException {

		return reserver.reserve(req);

	}

	public void cancel(ReserveId rsvId) throws ReserveException {

		canceler.cancel(rsvId);

	}

	public void cancelOfOwner(String owner) throws ReserveException {

		canceler.cancelOfOwner(owner);

	}

	public void modify(ReserveId rsvId, ReserveRequest req) throws ReserveException {

		modifier.modify(rsvId, req);

	}

	public void destroy(ReserveId rsvId) throws ReserveException {

		destroier.destroy(rsvId);

	}

	public void destroyOfOwner(String owner) throws ReserveException {

		destroier.destroyOfOwner(owner);

	}

	public void commit(ReserveId rsvId) throws ReserveException {

		ReserveOperation ope = rsvMgr.getCurrentOperation();
		commiter.commit(rsvId);
		rsvLogger.output(ope);

	}

	public void abort(ReserveId rsvId) throws ReserveException {

		aborter.abort(rsvId);

	}

	public synchronized ReserveStatus getStatus(ReserveId rsvId) throws ReserveException {

		return watcher.getStatus(rsvId);

	}

	public ReserveStatus[] getStatus(String owner, Calendar start,
			Calendar end, int nShowExpired) throws ReserveException {

		return watcher.getStatus(owner, start, end, nShowExpired);

	}

	public int availableNodeNum(Calendar start, Calendar end) throws ReserveException {

		return watcher.availableNodeNum(start, end);

	}

	public void stopServer() throws ReserveException {

		rsvMgr.stopServer();

	}

}
